package com.chy.blog_web.core.el;

import java.sql.Connection;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

import com.chy.blog_web.core.util.DateUtil;
import com.chy.blog_web.core.util.NumberUtils;
import com.chy.blog_web.core.util.StringUtil;
import org.apache.commons.lang3.StringUtils;

import javax.el.ELContext;

/**
 * 描述：EL 函数定义
 * 作者：chenhuiyan
 * 时间：2024/08/13
 */
public class ELFunction {

    /**
     * -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
     * 函数初始化区《START》
     * -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
     */

    /**
     * 参数集合
     */
    public static Map<String, Class<?>> parameterTypeMap = new HashMap<>();

    static {
        // 初始化参数类型
        initParameterType();
    }

    /**
     * 初始化参数类型
     */
    public static void initParameterType() {
        parameterTypeMap.put("integer", Integer.class);
        parameterTypeMap.put("string", String.class);
        parameterTypeMap.put("double", Double.class);
        parameterTypeMap.put("long", Long.class);
        parameterTypeMap.put("boolean", Boolean.class);
        parameterTypeMap.put("char", char.class);
        parameterTypeMap.put("float", Float.class);
        parameterTypeMap.put("short", Short.class);
        parameterTypeMap.put("object", Object.class);
        parameterTypeMap.put("map", Map.class);
        parameterTypeMap.put("list", List.class);
        parameterTypeMap.put("float[]", float[].class);
        parameterTypeMap.put("object[]", Object[].class);
        parameterTypeMap.put("int[]", int[].class);
        parameterTypeMap.put("double[]", double[].class);
        parameterTypeMap.put("string[]", String[].class);
        parameterTypeMap.put("ELContext", ELContext.class);
    }

    /**
     * 根据参数类型标识符，得到对应的参数类型
     *
     * @param parameterTypes
     * @return
     */
    public static Class<?>[] getParameterTypeClass(String parameterTypes) {
        if (StringUtils.isNotBlank(parameterTypes)) {
            String[] parameterTypeArray = parameterTypes.split(",");
            int length = parameterTypeArray.length;
            if (length > 0) {
                Class<?>[] parameterTypeClass = new Class<?>[length];
                for (int i = 0; i < length; i++) {
                    parameterTypeClass[i] = parameterTypeMap.get(parameterTypeArray[i]);
                }
                return parameterTypeClass;
            }
        }
        return null;
    }

    /**
     * 获取字符串长度
     *
     * @param str
     * @return
     */
    public static int len(String str) {
        return str.length();
    }

    /**
     * 是否为数字
     *
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 是否为空值
     *
     * @param str
     * @return
     */
    public static boolean isNull(String str) {
        return StringUtil.isNull(str);
    }

    /**
     * 不为空
     *
     * @param str
     * @return
     */
    public static boolean notNull(String str) {
        return StringUtil.notNull(str);
    }

    /**
     * 将字符串转为日期对象
     *
     * @param date
     * @return
     */
    public static Date toDate(String date) {
        if (date != null && !date.equals("")) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                return format.parse(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return new Date(System.currentTimeMillis());
    }

    /**
     * 转化成年月日格式的字符串
     *
     * @param date
     * @return
     */
    public static String getDateString(String date) {
        return DateUtil.getDateString(date);
    }

    /**
     * 获取日期的年度
     *
     * @param date
     * @return
     */
    public static String getYear(String date) {
        return DateUtil.getYear(date);
    }

    public static String getMonth(String date) {
        return DateUtil.getMonth(date);
    }

    /**
     * 获取当前日期
     *
     * @return
     */
    public static String systemDate() {
        return DateUtil.getSysDateString();
    }

    /**
     * 将当前日期转换成YYYY年MM月DD日格式
     *
     * @return
     */
    public static String systemDateChinese() {
        return DateUtil.setDateToChinese(systemDate());
    }

    /**
     * 将指定日期转换成YYYY年MM月DD日格式
     *
     * @return
     */
    public static String getDateChinese(String date) {
        return DateUtil.setDateToChinese(date);
    }

    /**
     * 将当前日期转换成Oct 21,2019格式
     *
     * @return
     */
    public static String systemDateEnglish() {
        return DateUtil.setDateToEnglish(systemDate());
    }

    /**
     * 将当前日期转换成Oct 2019格式
     *
     * @return
     */
    public static String systemDateEnglishMY() {
        return DateUtil.setDateToEnglishMY(systemDate());
    }

    /**
     * 将指定日期转换成Oct 21,2019格式
     *
     * @return
     */
    public static String getDateEnglish(String date) {
        return DateUtil.setDateToEnglish(date);
    }

    /**
     * 将指定日期转换成Oct 2019格式
     *
     * @return
     */
    public static String getDateEnglishMY(String date) {
        return DateUtil.setDateToEnglishMY(date);
    }

    public static String systemYear() {
        return DateUtil.getCurrentYear();
    }

    /**
     * v7迁移 获取当前年度后两位
     */
    public static String getCurrentYearTwo() {
        String yearLast = new SimpleDateFormat("yy", Locale.CHINESE).format(Calendar.getInstance().getTime());
        return yearLast;
    }

    public static int getDays(String newDate, String oldDate) {
        return DateUtil.getDays(newDate, oldDate);
    }

    public static String age(String bir) {
        String birYearString = DateUtil.getYear(bir);
        String currYearString = DateUtil.getCurrentYear();
        int age = 0;
        if (StringUtil.notNull(birYearString)) {
            int birYear = Integer.parseInt(birYearString);
            int currYear = Integer.parseInt(currYearString);
            age = currYear - birYear;
        }
        return age + "";
    }

    /**
     * 获取出生日期， 把年转换成当前年份
     *
     * @param birth 出生日期
     * @return
     */
    public static String birthDate(String birth) {
        return DateUtil.birthDate(birth);
    }

    /**
     * 字符转整数
     *
     * @param num
     * @return
     */
    public static int stringToInt(String num) {
        return StringUtil.toInt(num);
    }

    public static int getNum(Double d) {
        double x = d / 999;
        double y = d % 999;
        if (y > 0) {
            x = x + 1;
        }
        int i = (int) Math.floor(x);
        return i;
    }

    /**
     * 字符转数字
     *
     * @param num
     * @return
     */
    public static double stringToDouble(String num) {
        return StringUtil.toDouble(num);
    }

    /**
     * 数字累加
     *
     * @param nums
     * @return
     */
    public static float sum(float... nums) {
        float total = 0;
        if (nums != null) {
            for (float num : nums) {
                total += num;
            }
        }
        return total;
    }

    public static double getGs(String num) {
        double gs = 0.0;
        double nums = stringToDouble(num);
        nums = nums - 3500;
        // 应纳税所得额
        double border[] = {1500, 4500, 9000, 35000, 55000, 80000};
        // 税率
        double rate[] = {0.03, 0.1, 0.2, 0.25, 0.30, 0.35, 0.45};
        // 速算扣除数
        double shortcut[] = {0, 105, 555, 1005, 2755, 5505, 13505};
        if (nums > 0) {
            for (int i = 0; i < border.length; i++) {
                if (nums < border[i] || nums == border[i]) {
                    gs = nums * rate[i] - shortcut[i];
                    break;
                } else if (i == 5 && nums > border[i]) {
                    gs = nums * rate[i + 1] - shortcut[i + 1];
                    break;
                }
            }
        }
        return gs;
    }

    public static double divide(Double v1, Double v2, Integer scale) {
        return NumberUtils.divide(v1, v2, scale);
    }

    /**
     * 求和
     *
     * @param a
     * @param b
     * @return
     */
    public static double numSum(Double a, Double b) {
        double sum = 0;
        sum = a + b;
        return sum;
    }

    /**
     * 相减
     *
     * @param a
     * @param b
     * @return
     */
    public static double numSub(Double a, Double b) {
        double sub = 0;
        sub = a - b;
        return sub;
    }

    /**
     * 乘积
     *
     * @param a
     * @param b
     * @return
     */
    public static double numMul(Double a, Double b) {
        double mul = 0;
        mul = a * b;
        DecimalFormat df = new DecimalFormat("0.00");
        mul = Double.parseDouble(df.format(mul));
        return mul;
    }

    /**
     * 相除
     *
     * @param a
     * @param b
     * @return
     */
    public static double numDiv(Double a, Double b) {
        double div = 0;
        if (b != 0) {
            div = a / b;
            DecimalFormat df = new DecimalFormat("0.00");
            div = Double.parseDouble(df.format(div));
        }
        return div;
    }

    /**
     * 等于
     *
     * @param a
     * @return
     */
    public static String equalTo(String a) {
        return a;
    }

    /**
     * 组合字段
     *
     * @param a
     * @param b
     * @param flag
     * @return
     */
    public static String groupField(String a, String b, String flag) {
        return a + flag + b;
    }

    /**
     * 字段去空格
     *
     * @param a
     * @return
     */
    public static String trimField(String a) {
        return a.replaceAll(" ", "");
    }

    /**
     * 日期小于
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean dateLessThan(String date1, String date2) {
        if (null != date1 && !"".equals(date1.trim()) && null != date2 && !"".equals(date2.trim())) {
            SimpleDateFormat ymdSdf = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat ymSdf = new SimpleDateFormat("yyyy-MM");
            // 统一日期格式
            date1 = date1.replaceAll("/", "-");
            date2 = date2.replaceAll("/", "-");
            try {
                Date d1 = null;
                if (date1.length() >= 10) {
                    d1 = ymdSdf.parse(date1);
                } else if (date1.length() == 7) {
                    d1 = ymSdf.parse(date1);
                }

                Date d2 = null;
                if (date2.length() >= 10) {
                    d2 = ymdSdf.parse(date2);
                } else if (date2.length() == 7) {
                    d2 = ymSdf.parse(date2);
                }

                if (null != d1 && null != d2 && d1.before(d2)) {
                    return true;
                } else {
                    return false;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * 数组传参
     *
     * @param strs
     * @return
     */
    public static String strAppend(String... strs) {
        StringBuffer sBuffer = new StringBuffer();
        for (int i = 0; i < strs.length; i++) {
            sBuffer.append(strs[i]);
        }
        return sBuffer.toString();
    }

    /**
     * 日期早于系统当前日期
     *
     * @param date
     * @return
     */
    public static boolean dateLessThanSystemDate(String date) {
        if (null != date && !"".equals(date.trim())) {
            SimpleDateFormat ymdSdf = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat ymSdf = new SimpleDateFormat("yyyy-MM");
            date = date.replaceAll("/", "-");
            try {
                Date d = null;
                if (date.length() >= 10) {
                    d = ymdSdf.parse(date);
                } else if (date.length() == 7) {
                    d = ymSdf.parse(date);
                }

                if (null != d && d.before(new Date())) {
                    return true;
                } else {
                    return false;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return true;
        }
    }

    public static int roundIntByType(Double doubleValue, Integer type) {
        return NumberUtils.roundIntByType(doubleValue, type);
    }

    /**
     * v7迁移 保留位数
     *
     * @param v
     * @param scale 保留几位小数
     * @param type  0：始终对非零舍弃部分前面的数字加1 例如1.13=2 1：从不对舍弃部分前面的数字加1，即截短 例如1.13=1 2: 1.13=2为正 -1.13=-1为负 3: 1.13=1为正 -1.13=-2为负 4：四舍五入求整数 只计算小数点后一位 5：如果舍弃部分 > 0.5 四舍五入 0.5 = 0 0.51=1
     * @return
     */
    public static double round(Double v, Integer scale, Integer type) {
        return NumberUtils.round(v, scale, type);
    }

    public static int calAge(String bir, String sort) {
        int age = 0;
        if (StringUtil.isNull(bir))
            return age;
        String now = DateUtil.getSystemDate();
        // 当前年
        String nowYear = DateUtil.getYear(now);
        // 出生年
        String birYear = DateUtil.getYear(bir);
        age = Integer.parseInt(nowYear) - Integer.parseInt(birYear);
        if (StringUtil.isEqual(sort, "month")) {
            // 当前月
            int nowMonth = Integer.parseInt(DateUtil.getMonth(now));
            // 出生月
            int birMonth = Integer.parseInt(DateUtil.getMonth(bir));
            // 判断日期大小
            if (birMonth >= nowMonth && age > 0) {
                age = age - 1;
            }
        } else if (StringUtil.isEqual(sort, "day")) {
            // 判断日期大小
            boolean afer = DateUtil.isAfter(nowYear + "-" + DateUtil.getMonth(bir) + "-" + DateUtil.getDay(bir));
            if (afer && age > 0) {
                age = age - 1;
            }
        }
        return age;
    }

    /**
     * 计算工龄
     *
     * @param workDate   参加工作日期
     * @param breakYears 间断工龄
     * @return
     */
    public static int getWorkAge(String workDate, String breakYears) {
        int age = 0;
        if (StringUtil.isNull(workDate) || workDate.length() < 4)
            return 0;
        int workYear = StringUtil.toInt(workDate.substring(0, 4));
        if (workYear < 1000)
            return 0;
        age = StringUtil.toInt(DateUtil.getCurrentYear()) - workYear - StringUtil.toInt(breakYears);
        if (age < 0)
            return 0;
        return age;
    }

    public static int countYear(String date) {
        if (StringUtil.isNull(date) || date.length() < 4)
            return 0;
        int workYear = StringUtil.toInt(date.substring(0, 4));
        if (workYear < 1000)
            return 0;
        int year = StringUtil.toInt(DateUtil.getCurrentYear()) - workYear;
        if (year < 0)
            return 0;
        return year;
    }

    public static String cutString(String str, Integer b, Integer e) {
        if (StringUtil.isNull(str) || str.length() < e)
            return "";
        return str.substring(b, e);
    }

    public static boolean contains(String listStr,String str) {
        boolean flag = false;
        if(StringUtil.notNull(listStr) && StringUtil.notNull(str)){
            List<String> list = Arrays.asList(listStr.split(","));
            flag = list.contains(str);
        }
        return flag;
    }

    public static String StringAppend(String result,String appendStr) {
        return result+ appendStr;
    }

    /**
     * 判断两个日期大小
     * @param oneDate       第一个日期参数
     * @param twoDate       第二个日期参数
     * @param compare       比较符
     * @param dateFormat    日期转换格式（默认按照日期格式）
     * @return
     */
    public static boolean checkDateSize(String oneDate, String twoDate,String compare,String dateFormat) {
        if (StringUtil.isNull(oneDate) || StringUtil.isNull(twoDate)){
            return false;
        }
        try {
            SimpleDateFormat sdf = null;
            if(StringUtil.isNull(dateFormat)){
                sdf = new SimpleDateFormat("yyyy-MM-dd");
            }else{
                sdf = new SimpleDateFormat(dateFormat);
            }
            long one = sdf.parse(oneDate).getTime();
            long two = sdf.parse(twoDate).getTime();
            if(">".equals(compare) && one > two){
                return true;
            }else if(">=".equals(compare) && one >= two){
                return true;
            }else if("==".equals(compare) && one == two){
                return true;
            }else if("<".equals(compare) && one < two){
                return true;
            }else if("<=".equals(compare) && one <= two){
                return true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }
}
